package com.log.james.controller;

import com.log.james.entity.*;
import com.log.james.service.*;
import com.log.james.utils.IPChangeUtil;
import com.log.james.utils.JsonUtil;
import com.log.james.utils.ProtocolUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 流量请求
 */

@RestController
@Api(tags = "流量接口")
public class StreamDataController {

    private JsonUtil jsonUtil = new JsonUtil();
//    ip转换
    private IPChangeUtil ipChangeUtil = new IPChangeUtil();
//    根据端口找到协议
    private ProtocolUtil protocolUtil = new ProtocolUtil();
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private FlowService flowService;

    @Autowired
    private FwlogFlowService fwlogFlowService;

    @Autowired
    private FwlogService fwlogService;

    @Autowired
    private WebLogService webLogService;

    @Autowired
    private WebFlowService webFlowService;


    @PostMapping("/stream")
    @ApiOperation("流量数据接口")
    public R streamData(@RequestBody StreamRequestBean requestBean){
        Date startT = new Date(requestBean.getStartTime());
        Date endT = new Date(requestBean.getEndTime());
        String type = requestBean.getType();

        logger.info("从前端获取的数据为" + startT + " " + endT + " " + type);

        String startTime = sdf.format(startT);
        String endTime = sdf.format(endT);
//        将时间由String类型转换成Date
        Date st = new Date();
        Date et = new Date();
        try{
            st = sdf.parse(startTime);
            et = sdf.parse(endTime);
        }catch (ParseException e){
            e.printStackTrace();
        }
//        返回的详细数据
        List<StreamUnitData> streamUnitDatas = new LinkedList<>();
        List<Map<String,Object>> srcDatas = new LinkedList<>();
        List<Map<String,Object>> features = new LinkedList<>();
//        请求web流量
        if (type.equals("web")){
            //获得该时间点的预测流量值，上下限等所有信息
            List<WebFlow> webFlows = flowService.findFlowByTime(st,et);
            if (webFlows.size() == 0){
                streamUnitDatas.add(null);
            }else{
                for (WebFlow webFlow:webFlows){
                    StreamUnitData streamUnitData = new StreamUnitData(sdf.format(webFlow.getStarttime()),
                            sdf.format(webFlow.getEndtime()),webFlow.getCurstream(),webFlow.getUpstream(),webFlow.getDownstream());
                    streamUnitDatas.add(streamUnitData);
                }
            }

//            获取该时间段内对于城市的访问结果
            List<Map<String,Object>> addressNums = webLogService.findCityNumByTime(st,et);
            if (addressNums.size() == 0){
                srcDatas.add(null);
            }else{
                for (Map<String,Object> addressNum : addressNums){
                    Map<String,Object> srcData = new HashMap<>();
                    String city = (String)addressNum.get("address");
                    int  times = Integer.parseInt(String.valueOf(addressNum.get("num")));
                    srcData.put(city,times);

                    srcDatas.add(srcData);
                }
            }
//            获取该时间段内的状态码的返回结果
            List<Map<String,Object>> reactNums = webLogService.findReactNumByTime(st,et);
            if (reactNums.size() == 0){
                features.add(null);
            }else{
                for (Map<String,Object> reactNum : reactNums){
                    Map<String,Object> feature = new HashMap<>();
                    String reactCode = String.valueOf(reactNum.get("reactNum"));
                    int times = Integer.parseInt(String.valueOf(reactNum.get("num")));

                    feature.put(reactCode,times);
                    features.add(feature);
                }
            }


        }
//        请求防火墙流量
        else if (type.equals("firewall")){
            List<FwlogFlow> fwlogFlows = fwlogFlowService.findFwlogFlowByTime(st,et);
            if (fwlogFlows.size() == 0){
                streamUnitDatas.add(null);
            }else{
                for (FwlogFlow fwlogFlow:fwlogFlows){
                    StreamUnitData streamUnitData = new StreamUnitData(sdf.format(fwlogFlow.getStarttime()),
                            sdf.format(fwlogFlow.getEndtime()),fwlogFlow.getCurstream(),fwlogFlow.getUpstream(),fwlogFlow.getDownstream());

                    streamUnitDatas.add(streamUnitData);
                }
            }

//            获取城市访问情况
            List<Map<String,Object>> cityNums = fwlogService.findCityNumByTime(st,et);
            if (cityNums.size() == 0){
                srcDatas.add(null);
            }else{
                for (Map<String,Object> cityNum:cityNums){
                    Map<String,Object> srcData = new HashMap<>();
                    String city = String.valueOf(cityNum.get("address"));
                    int num = Integer.parseInt(String.valueOf(cityNum.get("num")));

                    srcData.put("name",city);
                    srcData.put("value",num);
                    srcDatas.add(srcData);
                }
            }

//            协议组访问情况
            List<Map<String,Object>> protocolNums = fwlogService.findProtocolByTime(st,et);
            if (protocolNums.size() == 0){
                features.add(null);
            }else{
                int outAreaNum = 0;
                for (Map<String,Object> protocolNum:protocolNums){
                    Map<String,Object> feature = new HashMap<>();
                    int destport = Integer.parseInt(String.valueOf(protocolNum.get("port")));
                    int num = Integer.parseInt(String.valueOf(protocolNum.get("num")));
                    String protocol = protocolUtil.protocol().get(destport);
                    if (protocol == null){
                        outAreaNum += num;
                    }else{
                        feature.put(protocol,num);
                        features.add(feature);
                    }
                }
                if (outAreaNum > 0){
                    Map<String,Object> outAreaFeature = new HashMap<>();
                    outAreaFeature.put("未知",outAreaNum);
                    features.add(outAreaFeature);
                }
            }
        }

        Map<String,Object> streamDataResponse = new HashMap<>();
        streamDataResponse.put("startTime",startTime);
        streamDataResponse.put("endTime",endTime);
        streamDataResponse.put("data",streamUnitDatas);
//        streamDataResponse.put("srcData",srcDatas);
        streamDataResponse.put("feature",features);

//        return R.ok().put("data",jsonUtil.mapToJson(streamDataResponse));
        return R.ok().put("data",streamDataResponse);
    }
}
